import { calcBASE64length } from "./lib";
import createImage from "./image";
import { COMPRESSERROR } from "./errorType";
import {STATIC_TIMEOUT, STATIC_RESPONSE_ERROR, STATIC_FILE_ERROR, STATIC_COMPRESS_ERROR, STATIC_EXCHANGE_ERROR} from './statusEnum'


// 默认最大质量
const defaultMaxQuality = 100;
// 默认最小的压缩质量
const defaultMinQuality = 0;
// 大图质量压成小图 差率 1kb ；比如规定最大2*1024*1024图片，3M的图片在向下压缩时允许最小2*1024*1024-1024
const defaultCompressDiff = 1024;
const CANVAS = document.createElement("canvas");
const CTX = CANVAS.getContext("2d");

/**
 * 压缩图片
 * @param {*} param0
 */
function imageTODataURL({ img, quality, fileType }) {
  const width = (CANVAS.width = img.width);
  const height = (CANVAS.height = img.height);
  CTX.clearRect(0, 0, width, height);
  CTX.drawImage(img, 0, 0, width, height);
  const base64 = CANVAS.toDataURL(fileType, quality / 100);
  CANVAS.width = 0;
  CANVAS.height = 0;
  return base64;
}

/**
 * 图片压缩算法
 * @param {*} param0
 */
const compressImage = ({
  base64: base64Image,
  maxSize,
  fileType,
  quality: defaultQuality
}) => {
  let compressBase64 = base64Image;
  // 最大的压缩率
  let compressMaxQuality = defaultMaxQuality;
  // 最小压缩率
  let compressMinQuality = defaultMinQuality;
  // 压缩得到最小的图片base64
  let minCompressBase = null;
  return new Promise((resolve, reject) => {
    const compressRecursion = ({ base64, quality }) => {
      try {
        createImage(base64)
          .then(image => {
            // 将图片的类型统一转换 指定类型 默认 JPEG，
            compressBase64 = imageTODataURL({
              img: image,
              quality,
              fileType
            });

            const compressSize = calcBASE64length(compressBase64);
            if (compressSize > maxSize) {
              compressMaxQuality = quality;
              const diffQuality = compressMaxQuality - compressMinQuality;
              if (diffQuality <= 2) {
                if (!minCompressBase) {
                  // TODO: 上传图片大小限制较小时，存在一轮压缩无法达到目的.这是考虑等比例压缩图片而非质量压缩
                  resolve({
                    result: true,
                    base64: compressBase64
                  });
                } else {
                  resolve({
                    result: true,
                    base64: minCompressBase || compressBase64
                  });
                }
              } else {
                const compressQuality = Math.ceil(
                  (compressMaxQuality + compressMinQuality) / 2
                );
                compressRecursion({
                  base64: compressBase64,
                  quality: compressQuality
                });
              }
            } else {
              minCompressBase = base64;
              if (compressSize < maxSize) {
                compressMaxQuality = 2 * quality > 100 ? 100 : 2 * quality;
                compressMinQuality = quality;
                const compressQuality = Math.ceil(
                  (compressMaxQuality + compressMinQuality) / 2
                );
                compressRecursion({
                  base64: compressBase64,
                  quality: compressQuality
                });
              } else {
                resolve({ result: true, base64: compressBase64 });
              }
            }
          })
          .catch(error => {
            reject({
              errorMsg: error, // 给开发者看的
              message: "图片压缩出错了",
              errorType: COMPRESSERROR,
              status:STATIC_COMPRESS_ERROR
            });
          });
      } catch (err) {
        reject({
          errorMsg: err, // 给开发者看的
          message: "图片压缩出错了",
          errorType: COMPRESSERROR,
          status:STATIC_COMPRESS_ERROR
        });
      }
    };
    compressRecursion({ base64: base64Image, quality: defaultQuality });
  });
};

export default async ({ base64, maxSize, fileType }) => {
  // 计算base64大小
  const size = calcBASE64length(base64);
  if (size > maxSize) {
    // 执行压缩
    const maxQuality = defaultMaxQuality;
    const minQuality = defaultMinQuality;
    const quality = Math.ceil((maxQuality + minQuality) / 2);
    try {
      const compressBase64 = await compressImage({
        base64,
        maxSize,
        fileType,
        quality
      });
      if (compressBase64.result) {
        const { base64: compressImage } = compressBase64;
        return { result: true, base64: compressImage };
      } else {
        return {
          errorMsg: "代码错误", // 给开发者看的
          message: "图片压缩出错了",
          errorType: COMPRESSERROR,
          status:STATIC_COMPRESS_ERROR
        };
      }
    } catch (error) {
      return {
        errorMsg: error, // 给开发者看的
        message: "图片压缩出错了",
        errorType: COMPRESSERROR,
        status:STATIC_COMPRESS_ERROR
      };
    }
  } else {
    return { result: true, base64: base64 };
  }
};
